ATOM Documentation

← Back to App

Desktop App Hosting Setup Guide

This guide walks through setting up Cloudflare R2 hosting for desktop app downloads.

Overview

  • **Build System**: Tauri (Rust + Web frontend)
  • **Storage**: Cloudflare R2 (S3-compatible)
  • **CDN**: Cloudflare Workers (optional, for faster downloads)
  • **Platforms**: macOS (dmg), Windows (msi/exe), Linux (deb/AppImage)

Prerequisites

  1. **Cloudflare Account** with R2 enabled
  2. **Rust** and **Node.js** installed locally
  3. **Tauri CLI**: cargo install tauri-cli --version "^2.0.0"

Step 1: Create Cloudflare R2 Bucket

1.1 Create Bucket

# Install wrangler CLI
npm install -g wrangler

# Login to Cloudflare
wrangler login

# Create R2 bucket
wrangler r2 bucket create atom-desktop-app

1.2 Get Your Account ID

# Your account ID is shown after login
# Or find it in Cloudflare dashboard: https://dash.cloudflare.com → Right sidebar

Step 2: Configure R2 Access Tokens

2.1 Create R2 API Token

  1. Go to: https://dash.cloudflare.com → R2 → Manage R2 API Tokens
  2. Create a new API token with permissions:
  • **Read** access to atom-desktop-app bucket
  • **Write** access to atom-desktop-app bucket
  • **List** access to buckets
  1. Copy the **Access Key ID** and **Secret Access Key**

2.2 Set Environment Variables

Add to your .env file or Vault secrets:

# Cloudflare R2 Configuration (Desktop App Storage)
DESKTOP_R2_ACCOUNT_ID=your_account_id_here
DESKTOP_R2_ACCESS_KEY=your_access_key_id_here
DESKTOP_R2_SECRET_KEY=your_secret_access_key_here
DESKTOP_R2_BUCKET=atom-desktop-app

**Important**: These secrets use DESKTOP_R2_ prefix to avoid conflicts with other R2 buckets (e.g., tenant file storage).

For Cloud deployment:

# Desktop app storage secrets
atom-cli secrets set DESKTOP_R2_ACCOUNT_ID=...
atom-cli secrets set DESKTOP_R2_ACCESS_KEY=...
atom-cli secrets set DESKTOP_R2_SECRET_KEY=...
atom-cli secrets set DESKTOP_R2_BUCKET=atom-desktop-app

Step 3: Set Up Custom Domain (Optional)

3.1 Configure R2 Custom Domain

# Create a public bucket for custom domain access
wrangler r2 bucket put atom-desktop-app --public

3.2 Add Custom Domain in Cloudflare Dashboard

  1. Go to: https://dash.cloudflare.com → R2 → atom-desktop-app
  2. Click "Settings" → "Public Access"
  3. Add custom domain: r2.atom-saas.com (or your subdomain)
  4. Configure DNS: Add CNAME record pointing to R2

3.3 DNS Configuration

Type: CNAME
Name: r2 (or your subdomain)
Target: [Cloudflare provides target]
Proxy: Yes (DNS only)

Step 4: Build Desktop App

4.1 Development Build

# Run with hot reload
npm run desktop:dev

4.2 Production Build

# Build for current platform
npm run desktop:build

# Build specific platform
npm run desktop:build:macos      # macOS universal binary
npm run desktop:build:windows    # Windows x64
npm run desktop:build:linux      # Linux x64

Build artifacts are created in:

  • macOS: src-tauri/target/release/bundle/dmg/
  • Windows: src-tauri/target/release/bundle/msi/ or bundle/nsis/
  • Linux: src-tauri/target/release/bundle/deb/ or bundle/appimage/

Step 5: Upload to R2

5.1 Upload Build Artifacts

# Upload version 1.0.0 builds to R2
npm run desktop:upload:r2

# Or specify custom version
npx tsx scripts/upload-to-r2.ts 1.0.1

This will:

  1. Upload all artifacts from desktop-builds/1.0.0/
  2. Create SHA256 checksums for each file
  3. Upload version.json with build metadata
  4. Update versions.json manifest
  5. Set latest-version.json pointer

5.2 Manual Upload (Alternative)

# Install AWS CLI (works with R2)
brew install awscli

# Configure AWS CLI for R2
aws configure set \
  --profile desktop_r2 \
  --endpoint-url https://${DESKTOP_R2_ACCOUNT_ID}.r2.cloudflarestorage.com

# Upload a file
aws s3 cp \
  ./Atom-SaaS-1.0.0.dmg \
  s3://atom-desktop-app/desktop-apps/1.0.0/Atom-SaaS-1.0.0.dmg \
  --profile desktop_r2 \
  --endpoint-url https://${DESKTOP_R2_ACCOUNT_ID}.r2.cloudflarestorage.com

Step 6: Download API

6.1 Test Download API

# Get latest version for auto-detected platform
curl "https://[tenant].atomagentos.com/api/desktop/download"

# Get specific platform
curl "https://[tenant].atomagentos.com/api/desktop/download?platform=darwin"

# Get specific version
curl "https://[tenant].atomagentos.com/api/desktop/download?platform=darwin&version=1.0.0"

6.2 Response Format

{
  "version": "1.0.0",
  "platform": "darwin",
  "artifact": "Atom-SaaS-1.0.0.dmg",
  "downloadUrl": "https://r2.atom-saas.com/desktop-apps/1.0.0/Atom-SaaS-1.0.0.dmg",
  "checksumUrl": "https://r2.atom-saas.com/desktop-apps/1.0.0/Atom-SaaS-1.0.0.dmg.sha256",
  "releaseNotes": "https://github.com/rush86999/atom-saas/releases/tag/v1.0.0"
}

Step 7: Integrate with Onboarding

The <DesktopDownload /> component is already integrated into the onboarding flow (Step 6 - Local Bridge Setup).

Users can download the desktop app during onboarding, which provides:

  • Local terminal control
  • Browser automation via Playwright
  • Background agent execution
  • 0 ACU consumption for local operations

Troubleshooting

Build Fails

# Check Rust installation
rustc --version  # Should be 1.70+ for Tauri 2.x

# Check Node.js version
node --version  # Should be 18+

# Clear build cache
cd src-tauri
cargo clean

Upload Fails

# Verify credentials
echo $DESKTOP_R2_ACCOUNT_ID
echo $DESKTOP_R2_ACCESS_KEY

# Test R2 connection
aws s3 ls \
  s3://atom-desktop-app/ \
  --profile desktop_r2 \
  --endpoint-url https://${DESKTOP_R2_ACCOUNT_ID}.r2.cloudflarestorage.com

Download API Returns Error

# Check environment variables are set
atom-cli secrets list | grep DESKTOP_R2

# Test R2 bucket access
curl "https://r2.atom-saas.com/desktop-apps/latest-version.json"

Code Signing (Production)

For distribution outside your organization, you need code signing:

**macOS**: Apple Developer certificate

# In src-tauri/tauri.conf.json:
"macOS": {
  "signingIdentity": "Developer ID Application: YOUR_NAME (TEAM_ID)"
}

**Windows**: Code signing certificate

# Install signtool on Windows
# Add certificate thumbprint to src-tauri/tauri.conf.json
"windows": {
  "certificateThumbprint": "YOUR_CERTIFICATE_THUMBPRINT"
}

File Structure After Build

desktop-builds/
└── 1.0.0/
    ├── Atom-SaaS-1.0.0.dmg
    ├── Atom-SaaS-1.0.0.dmg.sha256
    ├── Atom-SaaS-1.0.0-setup.exe
    ├── Atom-SaaS-1.0.0-setup.exe.sha256
    ├── atom-saas-1.0.0-amd64.deb
    ├── atom-saas-1.0.0-amd64.deb.sha256
    └── version.json

R2 Bucket Structure

atom-desktop-app/
├── desktop-apps/
│   ├── latest-version.json  → Symlink/pointer to current version
│   ├── versions.json          → All available versions
│   └── 1.0.0/
│       ├── Atom-SaaS-1.0.0.dmg
│       ├── Atom-SaaS-1.0.0.dmg.sha256
│       ├── Atom-SaaS-1.0.0-setup.exe
│       ├── Atom-SaaS-1.0.0-setup.exe.sha256
│       ├── atom-saas-1.0.0-amd64.deb
│       ├── atom-saas-1.0.0-amd64.deb.sha256
│       └── version.json
└── [future versions...]

Cost Estimates

**R2 Storage**: ~$0.015/GB/month

  • Each build ~150MB (all platforms)
  • 10 versions = 1.5GB = ~$0.02/month

**R2 Egress** (Class A): ~$0.009/GB (first 10TB) in US

  • 1000 downloads × 150MB = 150GB = ~$1.35

**Total**: Under $2/month for 1000 downloads

Next Steps

  1. Build your first desktop app: npm run desktop:build
  2. Upload to R2: npm run desktop:upload:r2
  3. Test download API: curl /api/desktop/download
  4. Integrate with onboarding flow (already done)
  5. Set up custom domain for CDN (optional)